//
//  UIImage+Download.m
//  MobileCRM
//
//  Created by winter on 16/3/2.
//  Copyright © 2016年 江苏金恒信息科技有限公司. All rights reserved.
//

#import "NSData+Download.h"
#import <objc/runtime.h>


///print log on console
#ifdef DEBUG
//#import "Developer.h"
#define JHLOG(fmt,...)\
{\
NSLog(@"DEBUG: %s %s ##Line-%d:\n"#fmt,__FILE__,__FUNCTION__,__LINE__,__VA_ARGS__);\
\
}
#else
#define JHLOG(fmt,...){}
#endif

@implementation NSData(Download)

+ (NSData *)wsDataWithContentsOfURL:(NSURL *)url key:(NSString *)key options:(NSDataReadingOptions)readOptionsMask error:(NSError *__autoreleasing *)errorPtr
{
    static NSCache *cache;
    static dispatch_once_t once_t;
    dispatch_once(&once_t, ^{
        cache = [NSCache new];
    });
    while ([cache objectForKey:[NSString stringWithFormat:@"_%@",key]])
    {
        [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:.5]];
    }
    if([cache objectForKey:key])
    {
        return [cache objectForKey:key];
    }
    // read from file
    NSString *cachePath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"activities"];
    JHLOG("cache path %@",cachePath);
    if([[NSFileManager defaultManager] fileExistsAtPath:[cachePath stringByAppendingPathComponent:key]])
    {
        NSData *dt = [NSData dataWithContentsOfFile:[cachePath stringByAppendingPathComponent:key] options:readOptionsMask error:errorPtr];
        if((*errorPtr))
        {
            JHLOG("%@  %@",(*errorPtr).localizedDescription,(*errorPtr).localizedFailureReason);
            return nil;
        }
        [cache setObject:dt forKey:key];
        return dt;
    }
    dispatch_queue_t fileQueue = dispatch_queue_create("com.nisco.jh.app", NULL);
    [cache setObject:@1 forKey:[NSString stringWithFormat:@"_%@",key]];
    //JHLOG(@"load from network",nil);
    NSData *data = [NSData dataWithContentsOfURL:url options:readOptionsMask error:errorPtr];
    [cache removeObjectForKey:[NSString stringWithFormat:@"_%@",key]];
    if((*errorPtr))
    {
        JHLOG("%@  %@",(*errorPtr).localizedDescription,(*errorPtr).localizedFailureReason);
        return nil;
    }
    /// set key
    [cache setObject:data forKey:key];
    dispatch_async(fileQueue, ^{
        ///write to file
        NSError *err;
        //if(![[NSFileManager defaultManager] fileExistsAtPath:cachePath isDirectory:YES])
        if(![[NSFileManager defaultManager] fileExistsAtPath:cachePath])
        {
            NSURL *cacheUrl = [NSURL fileURLWithPath:cachePath isDirectory:YES];
            if([[NSFileManager defaultManager] createDirectoryAtURL:cacheUrl withIntermediateDirectories:YES attributes:nil error:&err])
            {
                /*
                if(![cacheUrl setResourceValue:[NSNumber numberWithBool:YES] forKey:NSURLIsExcludedFromBackupKey error:&err])
                {
                    JHLOG("set file do not backup error: %@ %@",err.localizedDescription,err.localizedFailureReason);
                    return;
                }
                 */
            }
            else
                return;
        }
        if(![[NSFileManager defaultManager] fileExistsAtPath:[cachePath stringByAppendingPathComponent:key]])
        {
            if(![[NSFileManager defaultManager] createFileAtPath:[cachePath stringByAppendingPathComponent:key] contents:data attributes:nil])
            {
                return;
            }
        }
    });
    
    return data;
}
+ (NSData *)wsDataWithContentsOfURL:(NSURL *)url key:(NSString *)key options:(NSDataReadingOptions)readOptionsMask shouldCache:(BOOL) shouldCache error:(NSError *__autoreleasing *)errorPtr
{
    static NSCache *cache;
    static dispatch_once_t once_t;
    dispatch_once(&once_t, ^{
        cache = [NSCache new];
    });
    while ([cache objectForKey:[NSString stringWithFormat:@"_%@",key]])
    {
        [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:.5]];
    }
    if([cache objectForKey:key])
    {
        return [cache objectForKey:key];
    }
    // read from file
    NSString *cachePath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"activities"];
    //JHLOG("cache path %@",cachePath);
    if([[NSFileManager defaultManager] fileExistsAtPath:[cachePath stringByAppendingPathComponent:key]])
    {
        NSData *dt = [NSData dataWithContentsOfFile:[cachePath stringByAppendingPathComponent:key] options:readOptionsMask error:errorPtr];
        if((*errorPtr))
        {
            JHLOG("%@  %@",(*errorPtr).localizedDescription,(*errorPtr).localizedFailureReason);
            return nil;
        }
        if(shouldCache)
            [cache setObject:dt forKey:key];
        return dt;
    }
    dispatch_queue_t fileQueue = dispatch_queue_create("com.nisco.jh.app", NULL);
    [cache setObject:@1 forKey:[NSString stringWithFormat:@"_%@",key]];
    //JHLOG(@"load from network",nil);
    NSData *data = [NSData dataWithContentsOfURL:url options:readOptionsMask error:errorPtr];
    [cache removeObjectForKey:[NSString stringWithFormat:@"_%@",key]];
    if((*errorPtr))
    {
        JHLOG("%@  %@",(*errorPtr).localizedDescription,(*errorPtr).localizedFailureReason);
        return nil;
    }
    /// load nothing
    if(data.length==0)return nil;
    /// set key
    if(shouldCache)
    {
        if(data)
            [cache setObject:data forKey:key];
    }
    dispatch_async(fileQueue, ^{
        ///write to file
        NSError *err;
        //if(![[NSFileManager defaultManager] fileExistsAtPath:cachePath isDirectory:YES])
        if(![[NSFileManager defaultManager] fileExistsAtPath:cachePath])
        {
            NSURL *cacheUrl = [NSURL fileURLWithPath:cachePath isDirectory:YES];
            if([[NSFileManager defaultManager] createDirectoryAtURL:cacheUrl withIntermediateDirectories:YES attributes:nil error:&err])
            {
                /*
                 if(![cacheUrl setResourceValue:[NSNumber numberWithBool:YES] forKey:NSURLIsExcludedFromBackupKey error:&err])
                 {
                 JHLOG("set file do not backup error: %@ %@",err.localizedDescription,err.localizedFailureReason);
                 return;
                 }
                 */
            }
            else
                return;
        }
        if(![[NSFileManager defaultManager] fileExistsAtPath:[cachePath stringByAppendingPathComponent:key]])
        {
            if(![[NSFileManager defaultManager] createFileAtPath:[cachePath stringByAppendingPathComponent:key] contents:data attributes:nil])
            {
                return;
            }
        }
    });
    
    return data;
}

@end
